#include "listeningsocket.h"
#include "exception.hpp"

namespace utils
{

ListeningSocket::ListeningSocket( int port )
{
	m_nListeningFD = socket( AF_INET, SOCK_STREAM, 0 );
	if( !is_valid() )
	{
		throw Exception( "Could not create server socket." );
	}

	int on = 1;
	if( setsockopt ( m_nListeningFD, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 )
	{
		throw Exception( "Could not create server socket." );
	}

	if( !is_valid() )
	{
		throw Exception( "Invalid SocketFD" );
	}

	m_addr.sin_family = AF_INET;
	m_addr.sin_addr.s_addr = htonl( INADDR_ANY );
	m_addr.sin_port = htons( port );

	int bind_return = bind( m_nListeningFD, ( struct sockaddr * ) &m_addr, sizeof( m_addr ) );


	if( bind_return == -1 )
	{
		throw Exception( "Could not bind to port." );
	}

	if( !is_valid() )
	{
		throw Exception( "Invalid SocketFD" );
	}

	int listen_return = listen( m_nListeningFD, 3 );


	if( listen_return == -1 )
	{
		throw Exception( "Could not bind to port." );
	}

}

ListeningSocket::~ListeningSocket()
{
	close( m_nListeningFD );
}


int ListeningSocket::Accept()
{
	int addr_length = sizeof( m_addr );
	nNewSocketFD = accept( m_nListeningFD, ( sockaddr* ) &m_addr, ( socklen_t* ) &addr_length );

	if( nNewSocketFD <= 0 )
	{
		throw Exception( "Could not accept socket." );
	}
	else
	{
		return nNewSocketFD;
	}


}


} // namespace utils

